﻿using Bmz.IM.Communication;
using Bmz.IM.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Bmz.IM.Client
{
    public partial class MainForm : BaseForm
    {
        //string filename = string.Empty;

        public MainForm()
        {
            InitializeComponent();
            ClientEngineContext.Current.EventDict.Add(StructMessageType.InitMainForm,InitMainFormUserList);
            ClientEngineContext.Current.EventDict.Add(StructMessageType.Chat, InitChatForm);
            ClientEngineContext.Current.EventDict.Add(StructMessageType.FriendLogin, FriendLoginEvent);
            ClientEngineContext.Current.EventDict.Add(StructMessageType.FriendLogout, FriendLogoutEvent);
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            //filename = string.Format("{0}_FriendList.txt", EngineContext.Current.CurrentUser.UserId);
            //if (File.Exists(filename))
            //{
            //    StreamReader textReader = new StreamReader(filename);
            //    friendVOList = JsonConvert.DeserializeObject<List<FriendVO>>(textReader.ReadToEnd());
            //    textReader.Close();
            //    InitMainForm(friendVOList);
            //}
            //else
            //{
            Thread sendThread = new Thread(SendMessage);
            sendThread.Start();
            //}
        }

        private void SendMessage()
        {
            MessageVO messageVO = new MessageVO()
            {
                Type = StructMessageType.InitMainForm,
                Content = "GetUserList",
                FromUserId = ClientEngineContext.Current.CurrentUser.UserId,
                FromIp = ClientEngineContext.Current.CurrentUser.Ip,
                FromPort = ClientEngineContext.Current.CurrentUser.Port,
                ToUserId = "Server",
                ToIp = ConfigurationManager.AppSettings["ServerIp"],
                ToPort = int.Parse(ConfigurationManager.AppSettings["ServerPort"])
            };
            ClientEngineContext.Current.SendMessageUdp(messageVO);
        }

        private void InitMainFormUserList(MessageVO messageVO)
        {
            if (this.InvokeRequired)
            {
                Action<MessageVO> initMainFormUserList = InitMainFormUserList;
                this.Invoke(initMainFormUserList, messageVO);
            }
            else
            {
                //StreamWriter streamWriter = new StreamWriter(filename);
                //streamWriter.Write(messageVO.Content);
                //streamWriter.Close();
                List<FriendVO> friendList = JsonConvert.DeserializeObject<List<FriendVO>>(messageVO.Content);
                InitMainForm(friendList);
            }
        }

        private void InitMainForm(List<FriendVO> friendList)
        {
            List<string> folderList = friendList.Select(p => p.Folder).Distinct().ToList();
            foreach (string folderName in folderList)
            {
                TreeNode folderNode = new TreeNode();
                folderNode.Text = folderName;
                this.tvUserList.Nodes.Add(folderNode);
                foreach (FriendVO item in friendList.Where(p => p.Folder == folderName))
                {
                    TreeNode node = new TreeNode();
                    node.Text = item.UserName;
                    node.Tag = JsonConvert.SerializeObject(item);
                    node.ToolTipText = item.UserId;
                    if(item.CurrentState!=StructUserState.Offline)
                    {
                        node.BackColor = Color.Red;
                    }
                    folderNode.Nodes.Add(node);
                }
            }
        }

        private void FriendLoginEvent(MessageVO message)
        {
            UserVO user = JsonConvert.DeserializeObject<UserVO>(message.Content);
            FriendVO firendvo = null;
            foreach (TreeNode item in tvUserList.Nodes)
            {
                foreach (TreeNode item1 in item.Nodes)
                    if (item1.ToolTipText == user.UserId)
                    {
                        firendvo = JsonConvert.DeserializeObject<FriendVO>(item1.Tag.ToString());
                        firendvo.CurrentState=user.CurrentState;
                        firendvo.Ip = user.Ip;
                        firendvo.Port = user.Port;
                        item1.Tag = JsonConvert.SerializeObject(firendvo);
                        item1.BackColor = Color.Red;
                        break;
                    }
            }
        }

        private void FriendLogoutEvent(MessageVO messageVO)
        {
            UserVO logoutuser = JsonConvert.DeserializeObject<UserVO>(messageVO.Content);
            foreach(TreeNode item in tvUserList.Nodes)
            {
                foreach(TreeNode item1 in item.Nodes)
                    if(item1.ToolTipText==logoutuser.UserId)
                    {
                        item1.BackColor = Color.Gray;
                        break;
                    }
            }
        }

        private void InitChatForm(MessageVO receiveMessageTran)
        {
            if (this.InvokeRequired)
            {
                Action<MessageVO> initChatFormDelegate = InitChatForm;
                this.Invoke(initChatFormDelegate, receiveMessageTran);
            }
            else
            {
                ChatForm chatForm = null;
                if (!chatFormDict.ContainsKey(receiveMessageTran.FromUserId))
                {
                    FriendVO firendvo = null;
                    foreach (TreeNode item in tvUserList.Nodes)
                    {
                        foreach (TreeNode item1 in item.Nodes)
                            if (item1.ToolTipText == receiveMessageTran.FromUserId)
                            {
                                firendvo = JsonConvert.DeserializeObject<FriendVO>(item1.Tag.ToString());
                                break;
                            }
                    }

                    chatForm = new ChatForm(firendvo);
                    chatForm.Text = firendvo.UserName;
                    chatForm.Show();
                    chatFormDict.Add(receiveMessageTran.FromUserId, chatForm);

                }
                else
                {
                    chatForm = chatFormDict[receiveMessageTran.FromUserId];
                    chatForm.Show();
                }
                chatForm.ShowMessage(receiveMessageTran);
            }
        }

        private void tvUserList_DoubleClick(object sender, EventArgs e)
        {
            if (tvUserList.SelectedNode != null && tvUserList.SelectedNode.Level == 1)
            {
                FriendVO firendvo = JsonConvert.DeserializeObject<FriendVO>(tvUserList.SelectedNode.Tag.ToString());
                if (!chatFormDict.ContainsKey(firendvo.UserId))
                {
                    ChatForm chatForm = new ChatForm(firendvo);
                    chatForm.Text = firendvo.UserName;
                    chatForm.Show();
                    chatFormDict.Add(firendvo.UserId, chatForm);
                }
                else
                {
                    ChatForm chatForm = chatFormDict[firendvo.UserId];
                    chatForm.Show();
                }
            }
        }

        private void MainForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            MessageVO messageVO = new MessageVO()
            {
                Type = StructMessageType.Logout,
                Content =JsonConvert.SerializeObject( ClientEngineContext.Current.CurrentUser),
                FromUserId = ClientEngineContext.Current.CurrentUser.UserId,
                FromIp = ClientEngineContext.Current.CurrentUser.Ip,
                FromPort = ClientEngineContext.Current.CurrentUser.Port,
                ToUserId = "Server",
                ToIp = ConfigurationManager.AppSettings["ServerIp"],
                ToPort = int.Parse(ConfigurationManager.AppSettings["ServerPort"])
            };
            ClientEngineContext.Current.SendMessageUdp(messageVO);
            Application.Exit();
        }
    }
}
